﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zxb.DayWork.Logic;
using System.Data;
using System.Xml;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Threading;

namespace Zxb.OneTimeWork
{
    public class CasePic
    {
        public string CasePictureID;
        public string CaseID;
        public int CaseStyleID;
        public string PicUrl;
        public string SmallPicUrl;
        public int CasePictureTypeID;
        public string CasePictureTypeName;

        public CasePic(DataRow dr)
        {
            CasePictureID = dr["CasePictureID"].ToString();
            CaseID = dr["CaseID"].ToString();

            CaseStyleID = 0;
            int.TryParse(dr["CaseStyleID"].ToString(), out CaseStyleID);

            PicUrl = dr["PicUrl"].ToString();
            SmallPicUrl = dr["SmallPicUrl"].ToString();

            CasePictureTypeID = 0;
            int.TryParse(dr["CasePictureTypeID"].ToString(), out CasePictureTypeID);

            CasePictureTypeName = dr["CasePictureTypeName"].ToString();
        }
    }

    public class FakeCase
    {
        public string NewCaseKey;
        public string OriginalCaseID;
        //public long EstateID;
        //public int CaseStyleID;
        public RoomData Room;
        public CasePic Pic;
        public List<CasePic> PicList = new List<CasePic>();

        public FakeCase(string newid, string oldid, RoomData room, CasePic pic)
        {
            NewCaseKey = newid;
            OriginalCaseID = oldid;
            //EstateID = estateid;
            //CaseStyleID = sid;
            Room = room;
            Pic = pic;
            PicList.Add(pic);
        }
    }

    public class ParaRunParam
    {
        public string txt;
        public RoomData room;
        public MutipleThreadResetEvent MTReset;
        public ParaRunParam(string text, RoomData data, MutipleThreadResetEvent mtreset)
        {
            txt = text;
            room = data;
            MTReset = mtreset;
        }
    }

    public class FakeCaseWorker : BatchWorker
    {
        private static Dictionary<string, FakeCase> dic_CaseKeys = new Dictionary<string, FakeCase>();
        private static object objLock = new object();

        //DataTable sourceDT;
        List<RoomData> roomlist = new List<RoomData>();
        
        List<FakeCase> targetCaseList = new List<FakeCase>();

        Dictionary<string, string> dic_estID_estName = new Dictionary<string, string>();

        private static DataTable ReadDtEstateCity()
        {
            string sql = "select RealEstateID,RealEstateName,CityID from EstateManage";
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.ZxbReader, sql);
        }
        private static DataTable ReadDtRoomData()
        {
            string sql = "SELECT * FROM RoomData WHERE RoomData.RoomStyleXml IS NOT NULL and CityID=203";
            //string sql = "SELECT * FROM RoomData WHERE RoomData.RoomStyleXml IS NOT NULL ";
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.TaskReader, sql);
        }
        //private static DataTable ReadDtlocaltest()
        //{
        //    string sql = "SELECT * FROM t1 ";
        //    return DAL.ReadDt_ReturnNewIfNull(DB.Local, sql);
        //}

        private static DataTable ReadDtCasesPictures(string length, string width, string typeids)
        {
            string sql = string.Format("SELECT p.CasePictureID,p.CaseID,p.PicUrl,p.SmallPicUrl,c.CaseStyleID,p.CasePictureTypeID,p.CasePictureTypeName FROM CasesPictures p inner join Cases c on p.CaseID=c.CaseID WHERE p.Width={0} AND p.Length={1} AND p.CasePictureTypeID IN ({2})", length, width, typeids);
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.TaskReader, sql);
        }

        //private static DataTable ReadDtCasesPictures(int length, int width, string typeids)
        //{
        //    string sql = string.Format("SELECT p.CasePictureID,p.CaseID,p.PicUrl,p.SmallPicUrl,c.CaseStyleID,p.CasePictureTypeID,p.CasePictureTypeName FROM CasesPictures p inner join Cases c on p.CaseID=c.CaseID WHERE p.Width={0} AND p.Length={1} AND p.CasePictureTypeID IN ({2})", length, width, typeids);
        //    return DAL.ReadDt_ReturnNewIfNull(DB.TaskReader, sql);
        //}

        //private static DataTable GetDt(XmlDocument xmlDoc, string typeID, string typeIds)
        //{
        //    DataTable dt = new DataTable();
        //    XmlNode node = xmlDoc.SelectSingleNode(string.Format("rooms/room[@typeid='{0}']", typeID));
        //    if (node != null)
        //    {
        //        string length = node.Attributes["length"].Value;
        //        string width = node.Attributes["width"].Value;
        //        if (length != "0" && width != "0" && length != "" && width != "")
        //        {
        //            //dt = ReadDtCasesPictures(length + "00", width + "00", typeIds);
        //            dt = ReadDtCasesPictures(length, width, typeIds);
        //        }
        //    }
        //    return dt;
        //}

        private static List<CasePic> GetPics(XmlDocument xmlDoc, RoomConfig config)
        {
            List<CasePic> list = new List<CasePic>();
            XmlNode node = xmlDoc.SelectSingleNode(string.Format("rooms/room[@typeid='{0}']", config.TypeID));
            if (node != null)
            {
                string length = node.Attributes["length"].Value;
                string width = node.Attributes["width"].Value;

                if (length != "0" && width != "0" && length != "" && width != "")
                {
                    DataTable dt = ReadDtCasesPictures(length, width, config.CasePictureTypeIDs);
                    foreach (DataRow dr in dt.Rows)
                    {
                        list.Add(new CasePic(dr));
                        //list.Add(new CasePic(dr["CasePictureID"].ToString(), dr["CaseID"].ToString(), Convert.ToInt32(dr["CaseStyleID"]), dr["PicUrl"].ToString(), dr["SmallPicUrl"].ToString(),dr[""]));
                    }
                }
            }
            return list;
        }

        private static List<FakeCase> ListMutiply(List<FakeCase> list1, List<FakeCase> list2)
        {
            List<FakeCase> productList = new List<FakeCase>();
            foreach (FakeCase preCase in list1)
            {
                foreach (FakeCase sufCase in list2)
                {
                    if (preCase.Pic.CaseStyleID == sufCase.Pic.CaseStyleID)
                    {
                        string newid = string.Concat(preCase.NewCaseKey, "-", sufCase.NewCaseKey);
                        string oldid = preCase.OriginalCaseID == sufCase.OriginalCaseID ? preCase.OriginalCaseID : "";
                        FakeCase f = new FakeCase(newid, oldid, preCase.Room, preCase.Pic);
                        List<CasePic> list = new List<CasePic>();
                        foreach (CasePic pic in preCase.PicList)
                        {
                            list.Add(pic);
                        }
                        list.Add(sufCase.Pic);
                        f.PicList = list;

                        productList.Add(f);
                    }
                }
            }
            return productList;
        }

        private static void List_To_Dic(List<FakeCase> list)
        {
            foreach (FakeCase fc in list)
            {
                lock (objLock)
                {
                    dic_CaseKeys[fc.NewCaseKey] = fc;
                }
            }
        }

        private static Dictionary<RoomConfig, List<CasePic>> ProcessXml(XmlDocument xmlDoc)
        {
            //dic_Config_Pics.Clear();
            Dictionary<RoomConfig, List<CasePic>> dic_Config_Pics = new Dictionary<RoomConfig, List<CasePic>>();
            foreach (RoomConfig config in RoomConfig.ConfigList)
            {
                List<CasePic> list = GetPics(xmlDoc, config);
                dic_Config_Pics[config] = list;
            }
            return dic_Config_Pics;
        }

        private static void AutoProcess(string txt, RoomData room)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(txt);

            Dictionary<RoomConfig, List<CasePic>> dic_Config_Pics = ProcessXml(xmlDoc);

            int count = 0;
            foreach (List<CasePic> picList in dic_Config_Pics.Values)
            {
                if (picList.Count > 0)
                {
                    count++;
                }
            }
            if (count >= 4)
            {
                //sum1++;

                List<FakeCase> result = new List<FakeCase>();
                foreach (RoomConfig config in RoomConfig.ConfigList)
                {
                    List<FakeCase> tmpList = new List<FakeCase>();
                    if (dic_Config_Pics.ContainsKey(config))
                    {
                        foreach (CasePic pic in dic_Config_Pics[config])
                        {
                            FakeCase fc = new FakeCase(string.Concat(config.SimpleMark, pic.CasePictureID), pic.CaseID, room, pic);
                            tmpList.Add(fc);
                        }
                    }
                    if (tmpList.Count == 0)
                    {
                        continue;
                    }
                    if (result.Count == 0)
                    {
                        result = tmpList;
                        continue;
                    }
                    result = ListMutiply(result, tmpList);
                }
                //foreach (FakeCase c in result)
                //{
                //    string sql = string.Format("insert into [test1].[dbo].[cases1] (caseid,oldcaseid,estateid,styleid,cityid) values ('{0}','{1}','{2}','{3}','{4}')", c.NewCaseKey, c.OriginalCaseID, c.EstateID, c.CaseStyleID, "202");
                //    DAL.SimpleInsert(DB.Local, sql);
                //}
                List_To_Dic(result);//去除重复key

                lock (objLock)
                {
                    Console.WriteLine(dic_CaseKeys.Keys.Count);
                }
                
            }
        }

        public static int currentRoom = 0;
        public static void ParaRun(object obj)
        {
            ParaRunParam myparam = (ParaRunParam)obj;
            AutoProcess(myparam.txt, myparam.room);
            myparam.MTReset.SetOne();
            Console.WriteLine(currentRoom++);
        }

        protected override void ReadData()
        {
            //DataTable ddd = ReadDtlocaltest();
            //sourceDT = ReadDtRoomData();
            DataTable dt = ReadDtRoomData();
            foreach (DataRow dr in dt.Rows)
            {
                roomlist.Add(new RoomData(dr));
            }

            DataTable estatemanage = ReadDtEstateCity();
            foreach (DataRow dr in estatemanage.Rows)
            {
                string eid = dr["RealEstateID"].ToString();
                string ename = dr["RealEstateName"].ToString();
                dic_estID_estName[eid] = ename;
            }
        }

        protected override void ProcessData()
        {
            int sum1 = 0;
            int now = 0;

            MutipleThreadResetEvent mtrEvent = new MutipleThreadResetEvent(roomlist.Count);

            foreach(RoomData room in roomlist)
            {
                string txt = room.RoomStyleXml;
                if (txt.Length == 0)
                {
                    mtrEvent.SetOne();
                    continue;
                }
                //AutoProcess(txt, room);
                ParaRunParam myparam = new ParaRunParam(txt, room, mtrEvent);
                ThreadPool.QueueUserWorkItem(ParaRun, myparam);

                Console.WriteLine(now++);

            }

            mtrEvent.WaitAll();

            //去除真实案例
            List<string> deleteList = new List<string>();
            foreach (string key in dic_CaseKeys.Keys)
            {
                if (dic_CaseKeys[key].OriginalCaseID.Length > 0)
                {
                    deleteList.Add(key);
                }
            }
            foreach (string key in deleteList)
            {
                dic_CaseKeys.Remove(key);
            }

            

            List<FakeCase> fcList = new List<FakeCase>();
            
            foreach (string key in dic_CaseKeys.Keys)
            {
                fcList.Add(dic_CaseKeys[key]);

                FakeCase fcase = dic_CaseKeys[key];
                CaseModel casemodel = CaseModel.GetCaseModel(fcase, dic_estID_estName);
                int caseid = CaseModel.InsertCase(casemodel);
                if (caseid == 0)
                {
                    continue;
                }

                
                //CasePic pic = fcase.Pic;

                for (int i = 0; i < fcase.PicList.Count; i++)
                {
                    CasePic pic = fcase.PicList[i];
                    CasePicModel picmodel = new CasePicModel(pic, caseid, i);
                    picmodel.InsertDB();
                }
                CasePicModel pmodel = CasePicModel.GetRoomPic(fcase.Room.RoomPic, caseid, fcase.PicList.Count);
                pmodel.InsertDB();
               
            }

            
            Console.WriteLine(sum1);

            try
            {
                var query
                = from f in fcList.AsEnumerable()
                  join e in ReadDtEstateCity().AsEnumerable()
                  on f.Room.EstateID equals e.Field<long>("RealEstateID")
                  select new
                  {
                      CaseKey = f.NewCaseKey,
                      RealEstateID = f.Room.EstateID,
                      CityID = e.Field<int>("CityID")
                  };

                var query2
                    = from f in query
                      join c in CityConfig.CityList
                      on f.CityID equals c.CityID
                      select new
                      {
                          CaseKey = f.CaseKey,
                          RealEstateID = f.RealEstateID,
                          CityID = f.CityID,
                          UserID = c.WeiKe_UserID
                      };
                foreach (var item in query2)
                {
                    CaseModel c = new CaseModel();
                    //c.CasePicID=
                    c.CityID = item.CityID;
                    //c.CityName=
                    c.EstateID = item.RealEstateID;
                    //c.EstateName=
                    c.IsValid = 1;
                    c.PicCount = 4;
                    //c.PicUrl=
                    //c.SmallPicUrl=
                    c.WeiKe_UserID = item.UserID;

                    //targetCaseList.Add(
                }

                var query_groupby_city
                    = from q in query
                      group q by q.CityID into g
                      select new
                      {
                          CityID = g.Key,
                          CasesNum = g.Count()
                      };
                foreach (var item in query_groupby_city)
                {
                    Console.WriteLine(string.Concat(item.CityID, ": ", item.CasesNum));
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
        }

        protected override void WriteData()
        {
            
        }
    }
}
